home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / internet / amitcp3.0b / src.lha / src / util / ifconfig / ifconfig.c next >
Encoding:
C/C++ Source or Header  |  1996-09-08  |  24.3 KB  |  881 lines

  1. static char rcsid[] =
  2.   "$Id: ifconfig.c,v 3.1 1994/02/22 03:28:22 ppessi Exp $";
  3. /*
  4.  * ifconfig.c --- Configure Network Interfaces
  5.  *
  6.  * Author: Pekka Pessi <Pekka.Pessi@hut.fi>
  7.  *
  8.  * Copyright © 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
  9.  *            Helsinki University of Technology, Finland.
  10.  *            All rights reserved.
  11.  *
  12.  * Created      : Sat May 15 04:12:15 1993 ppessi
  13.  * Last modified: Tue Feb 22 01:35:17 1994 ppessi
  14.  */
  15.  
  16. #include "ifconfig_rev.h"
  17. static const char version[] = VERSTAG " "
  18.      "Copyright © 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>\n"
  19.                       "Helsinki University of Technology, Finland.\n"
  20.                       "All rights reserved.\n"
  21. "@(#) Copyright © 1983 The Regents of the University of California.\n"
  22.                       "All rights reserved.\n";
  23.  
  24. /****** netutil.doc/ifconfig ************************************************
  25.  
  26.    NAME
  27.         ifconfig - configure network interface parameters
  28.  
  29.    VERSION
  30.         $Id: ifconfig.c,v 3.1 1994/02/22 03:28:22 ppessi Exp $
  31.  
  32.    SYNOPSIS
  33.         ifconfig interface address_family [address [dest_address]] [params]
  34.         ifconfig interface [address_family]
  35.  
  36.    DESCRIPTION
  37.         ifconfig is used to assign an address to a network interface and/or
  38.         configure network interface parameters.  ifconfig must be used at
  39.         boot time to define the network address of each interface present on
  40.         a machine.  It can also be used at other times to redefine an
  41.         interface's address or other operating parameters.
  42.  
  43.    PARAMETERS
  44.         interface     A string of the interface name concatenated with unit
  45.                       numver, for example `eth0'.  The AmiTCP/IP network
  46.                       interfaces are defined in the `AmiTCP:db/interface'
  47.                       file.  For example, a interface sl corresponds by
  48.                       default to `Devs:networks/rhcslip.device'.
  49.  
  50.         address_family
  51.  
  52.                       Name of protocol on which naming scheme is based.  An
  53.                       interface can receive transmissions in differing
  54.                       protocols, each of which may require separate naming
  55.                       schemes.  Therefore, it is necessary to specify the
  56.                       address_family, which may affect interpretation of the
  57.                       remaining parameters on the command line.  The only
  58.                       address family currently supported is inet (DARPA-
  59.                       Internet family).
  60.  
  61.         address       Either a host name present in the host name database,
  62.                       (SEE hosts), or a DARPA Internet address
  63.                       expressed in Internet standard "dot notation".  The
  64.                       host number can be omitted on 10-Mbyte/second Ethernet
  65.                       interfaces (which use the hardware physical address),
  66.                       and on interfaces other than the first.
  67.  
  68.         dest_address  Address of destination system.  Consists of either a
  69.                       host name present in the host name database, hosts(4),
  70.                       or a DARPA Internet address expressed in Internet
  71.                       standard "dot notation".
  72.  
  73.    SWITCHES
  74.         The following operating parameters can be specified:
  75.  
  76.          up           Mark an interface "up". Enables interface after an
  77.                       "ifconfig down."  Occurs automatically when setting the
  78.                       address on an interface.  Setting this flag has no
  79.                       effect if the hardware is "down".
  80.  
  81.          down         Mark an interface "down".  When an interface is marked
  82.                       "down", the system will not attempt to transmit
  83.                       messages through that interface. If possible, the
  84.                       interface will be reset to disable reception as well.
  85.                       This action does not automatically disable routes
  86.                       using the interface.
  87.  
  88.         arp           Enable the use of Address Resolution Protocol in
  89.                       mapping between network level addresses and link-level
  90.                       addresses (default).
  91.  
  92.         -arp          Disable the use of Address Resolution Protocol.
  93.  
  94.          metric n     Set the routing metric of the interface to n, default
  95.                       0.  The routing metric is used by the routing protocol
  96.                       (see gated).  Higher metrics have the effect of making
  97.                       a route less favorable; metrics are counted as
  98.                       additional hops to the destination network or host.
  99.  
  100.          debug        Enable driver-dependent debugging code. This usually
  101.                       turns on extra console error logging.
  102.  
  103.         -debug        Disable driver-dependent debugging code.
  104.  
  105.          netmask mask (Inet only) Specify how much of the address to reserve
  106.                       for subdividing networks into sub-networks.  mask
  107.                       includes the network part of the local address, and
  108.                       the subnet part which is taken from the host field of
  109.                       the address.  mask can be specified as a single hexa-
  110.                       decimal number with a leading 0x, with a dot-notation
  111.                       Internet address, or with a pseudo-network name listed
  112.                       in the file AmiTCP:db/networks.  `mask' contains 1's
  113.                       for each bit position in the 32-bit address that are
  114.                       to be used for the network and subnet parts, and 0's
  115.                       for the host part.  mask should contain at least the
  116.                       standard network portion, and the subnet field should
  117.                       be contiguous with the network portion.
  118.  
  119.         broadcast    (Inet only) Specify the address that represents
  120.                       broadcasts to the network.  The default broadcast
  121.                       address is the address with a host part of all 1's.
  122.  
  123.         The command:
  124.  
  125.              ifconfig interface/unit
  126.  
  127.         with no optional command arguments supplied displays the current
  128.         configuration for interface.  If address_family is specified,
  129.         ifconfig reports only the details specific to that address family.
  130.  
  131.    DIAGNOSTICS
  132.         Messages indicating that the specified interface does not exist, the
  133.         requested address is unknown, or the user is not privileged and
  134.         tried to alter an interface's configuration.
  135.  
  136.    EXAMPLES
  137.         ifconfig lo0 127.0.0.1
  138.  
  139.                 This command marks internal loopback device "UP", and
  140.                 attach an inet address 127.0.0.1 to it.
  141.  
  142.         ifconfig cslip0 inet 193.102.4.144 193.102.4.129
  143.  
  144.                 This command starts the CSLIP driver, attach an
  145.                 address 193.102.4.144 (our internet address) and a
  146.                 destination address 193.102.4.129 (the internet
  147.                 address of the host you are connecting) to it.
  148.  
  149.         ifconfig eth0 inet 193.124.100.64 netmask 255.255.255.192 -arp
  150.  
  151.                 This command loads an ethernet driver (by default for the
  152.                 Commodore A2065 Ethernet adapter unit 0), marks it "up",
  153.                 disables ARP protocol for it, attaches an inet address
  154.                 193.124.100.65 to it and sets its netmask to
  155.                 255.255.255.192.  A bitwise logical and of netmask and
  156.                 address for the interface forms a subnet address, in this
  157.                 case 193.124.100.64.  All packets aimed to hosts with same
  158.                 subnet address (that is hosts 193.124.100.64 -
  159.                 193.124.100.127) are routed to this interface.
  160.  
  161.    FILES
  162.         AmiTCP:db/interfaces
  163.  
  164.    SEE ALSO
  165.         netstat, hosts, arp, "net/if.h", "net/sana2tags.h"
  166.  
  167. *****************************************************************************
  168. *
  169. */
  170.  
  171. /*
  172.  * Copyright © 1983 Regents of the University of California.
  173.  * All rights reserved.
  174.  *
  175.  * Redistribution and use in source and binary forms, with or without
  176.  * modification, are permitted provided that the following conditions
  177.  * are met:
  178.  * 1. Redistributions of source code must retain the above copyright
  179.  *    notice, this list of conditions and the following disclaimer.
  180.  * 2. Redistributions in binary form must reproduce the above copyright
  181.  *    notice, this list of conditions and the following disclaimer in the
  182.  *    documentation and/or other materials provided with the distribution.
  183.  * 3. All advertising materials mentioning features or use of this software
  184.  *    must display the following acknowledgement:
  185.  *    This product includes software developed by the University of
  186.  *    California, Berkeley and its contributors.
  187.  * 4. Neither the name of the University nor the names of its contributors
  188.  *    may be used to endorse or promote products derived from this software
  189.  *    without specific prior written permission.
  190.  *
  191.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  192.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  193.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  194.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  195.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  196.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  197.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  198.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  199.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  200.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  201.  * SUCH DAMAGE.
  202.  */
  203.  
  204. #ifdef AMIGA
  205. #if __SASC
  206. #include <proto/socket.h>
  207. #elif __GNUC__
  208. #include <inline/socket.h>
  209. #else
  210. #include <clib/socket_protos.h>
  211. #endif
  212. #define ioctl IoctlSocket
  213. #endif /* AMIGA */
  214.  
  215. #include <sys/param.h>
  216. #include <sys/socket.h>
  217. #include <sys/ioctl.h>
  218.  
  219. #include <net/if.h>
  220. #include <netinet/in.h>
  221. #include <arpa/inet.h>
  222.  
  223. #ifdef NS
  224. #define    NSIP
  225. #include <netns/ns.h>
  226. #include <netns/ns_if.h>
  227. #endif
  228.  
  229. #include <netdb.h>
  230.  
  231. #ifdef ISO
  232. #define EON
  233. #include <netiso/iso.h>
  234. #include <netiso/iso_var.h>
  235. #endif
  236.  
  237. #ifdef notyet
  238. #include <unistd.h>
  239. #endif
  240. #include <stdio.h>
  241. #include <errno.h>
  242. #include <ctype.h>
  243. #include <stdlib.h>
  244. #include <string.h>
  245.  
  246. struct    ifreq        ifr, ridreq;
  247. struct    ifaliasreq    addreq;
  248. #ifdef ISO
  249. struct    iso_ifreq    iso_ridreq;
  250. struct    iso_aliasreq    iso_addreq;
  251. #endif
  252. struct    sockaddr_in    netmask;
  253.  
  254. char    name[1024];
  255. int    flags;
  256. int    metric;
  257. int    setaddr;
  258. int    setipdst;
  259. int    doalias;
  260. int    clearaddr;
  261. int    newaddr = 1;
  262. int    s;
  263. extern    int errno;
  264.  
  265. #ifdef NS
  266. int    nsellength = 1;
  267. #endif
  268.  
  269. void Perror(char *cmd);
  270. void status(void);
  271. void printb(char *s, register unsigned short v, register char *bits);
  272.  
  273. void setifflags(char *, short);
  274. void setifaddr(char *, short);
  275. void setifdstaddr(char *, short);
  276. void setifnetmask(char *, short);
  277. void setifmetric(char *, short);
  278. void setifbroadaddr(char *, short);
  279. void setifipdst(char *, short);
  280. void notealias(char *, short);
  281. void setsnpaoffset(char *, short);
  282. void setnsellength(char *, short);
  283.  
  284. #define    NEXTARG        0xffffff
  285.  
  286. struct    cmd {
  287.     char    *c_name;
  288.     int    c_parameter;        /* NEXTARG means next argv */
  289.     void     (*c_func)(char *, short);
  290. } cmds[] = {
  291.     { "up",        IFF_UP,        setifflags } ,
  292.     { "down",    -IFF_UP,    setifflags },
  293.     { "trailers",    -IFF_NOTRAILERS,setifflags },
  294.     { "-trailers",    IFF_NOTRAILERS,    setifflags },
  295.     { "arp",    -IFF_NOARP,    setifflags },
  296.     { "-arp",    IFF_NOARP,    setifflags },
  297.     { "debug",    IFF_DEBUG,    setifflags },
  298.     { "-debug",    -IFF_DEBUG,    setifflags },
  299.     { "alias",    IFF_UP,        notealias },
  300.     { "-alias",    -IFF_UP,    notealias },
  301.     { "delete",    -IFF_UP,    notealias },
  302. #ifdef notdef
  303. #define    EN_SWABIPS    0x1000
  304.     { "swabips",    EN_SWABIPS,    setifflags },
  305.     { "-swabips",    -EN_SWABIPS,    setifflags },
  306. #endif
  307.     { "netmask",    NEXTARG,    setifnetmask },
  308.     { "metric",    NEXTARG,    setifmetric },
  309.     { "broadcast",    NEXTARG,    setifbroadaddr },
  310.     { "ipdst",    NEXTARG,    setifipdst },
  311. #ifdef ISO
  312.     { "snpaoffset",    NEXTARG,    setsnpaoffset },
  313.     { "nsellength",    NEXTARG,    setnsellength },
  314. #endif
  315.     { 0,        0,        setifaddr },
  316.     { 0,        0,        setifdstaddr },
  317. };
  318.  
  319. void in_status(int);
  320. void in_getaddr(char *addr, int which);
  321. #ifdef NS
  322. /*
  323.  * XNS support liberally adapted from
  324.  * code written at the University of Maryland
  325.  * principally by James O'Toole and Chris Torek.
  326.  */
  327. void xns_status(int);
  328. void xns_getaddr(char *addr, int which);
  329. #endif
  330. #ifdef ISO
  331. void iso_status(int);
  332. void iso_getaddr(char *addr, int which);
  333. #endif
  334.  
  335. /* Known address families */
  336. struct afswtch {
  337.     char *af_name;
  338.     short af_af;
  339.     void (*af_status)(int);
  340.     void (*af_getaddr)(char *, int);
  341.     int af_difaddr;
  342.     int af_aifaddr;
  343.     caddr_t af_ridreq;
  344.     caddr_t af_addreq;
  345. } afs[] = {
  346. #define C(x) ((caddr_t) &x)
  347.     { "inet", AF_INET, in_status, in_getaddr,
  348.          SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) },
  349. #ifdef NS
  350.     { "ns", AF_NS, xns_status, xns_getaddr,
  351.          SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) },
  352. #endif
  353. #ifdef ISO
  354.     { "iso", AF_ISO, iso_status, iso_getaddr,
  355.          SIOCDIFADDR_ISO, SIOCAIFADDR_ISO, C(iso_ridreq), C(iso_addreq) },
  356. #endif
  357.     { 0,    0,        0,        0 }
  358. };
  359.  
  360. struct afswtch *afp;    /*the address family being set or asked about*/
  361.  
  362. main(argc, argv)
  363.     int argc;
  364.     char *argv[];
  365. {
  366.     int af = AF_INET;
  367.     register struct afswtch *rafp;
  368.  
  369.     if (argc < 2) {
  370.         fprintf(stderr, "usage: ifconfig interface\n%s%s%s%s%s",
  371.             "\t[ [ af ] [ address [ dest_addr ] ] [ up ] [ down ]",
  372.                 "[ netmask mask ] ]\n",
  373.             "\t[ metric n ]\n",
  374.             "\t[ trailers | -trailers ]\n",
  375.             "\t[ arp | -arp ]\n");
  376.         exit(1);
  377.     }
  378.     argc--, argv++;
  379.     strncpy(name, *argv, sizeof(name));
  380.     strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
  381.     argc--, argv++;
  382.     if (argc > 0) {
  383.         for (afp = rafp = afs; rafp->af_name; rafp++)
  384.             if (strcmp(rafp->af_name, *argv) == 0) {
  385.                 afp = rafp; argc--; argv++;
  386.                 break;
  387.             }
  388.         rafp = afp;
  389.         af = ifr.ifr_addr.sa_family = rafp->af_af;
  390.     }
  391.     s = socket(af, SOCK_DGRAM, 0);
  392.     if (s < 0) {
  393.         perror("ifconfig: socket");
  394.         exit(1);
  395.     }
  396.     if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
  397.         Perror("ioctl (SIOCGIFFLAGS)");
  398.         exit(1);
  399.     }
  400.     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  401.     flags = ifr.ifr_flags;
  402.     if (ioctl(s, SIOCGIFMETRIC, (caddr_t)&ifr) < 0)
  403.         perror("ioctl (SIOCGIFMETRIC)");
  404.     else
  405.         metric = ifr.ifr_metric;
  406.     if (argc == 0) {
  407.         status();
  408.         exit(0);
  409.     }
  410.     while (argc > 0) {
  411.         register struct cmd *p;
  412.  
  413.         for (p = cmds; p->c_name; p++)
  414.             if (strcmp(*argv, p->c_name) == 0)
  415.                 break;
  416.         if (p->c_name == 0 && setaddr)
  417.             p++;    /* got src, do dst */
  418.         if (p->c_func) {
  419.             if (p->c_parameter == NEXTARG) {
  420.                 (*p->c_func)(argv[1], 0);
  421.                 argc--, argv++;
  422.             } else
  423.                 (*p->c_func)(*argv, p->c_parameter);
  424.         }
  425.         argc--, argv++;
  426.     }
  427. #ifdef ISO
  428.     if (af == AF_ISO)
  429.         adjust_nsellength();
  430. #endif
  431. #ifdef NS
  432.     if (setipdst && af==AF_NS) {
  433.         struct nsip_req rq;
  434.         int size = sizeof(rq);
  435.  
  436.         rq.rq_ns = addreq.ifra_addr;
  437.         rq.rq_ip = addreq.ifra_dstaddr;
  438.  
  439.         if (setsockopt(s, 0, SO_NSIP_ROUTE, &rq, size) < 0)
  440.             Perror("Encapsulation Routing");
  441.     }
  442. #endif
  443.     if (clearaddr) {
  444.         int ret;
  445.         strncpy(rafp->af_ridreq, name, sizeof ifr.ifr_name);
  446.         if ((ret = ioctl(s, rafp->af_difaddr, rafp->af_ridreq)) < 0) {
  447.             if (errno == EADDRNOTAVAIL && (doalias >= 0)) {
  448.                 /* means no previous address for interface */
  449.             } else
  450.                 Perror("ioctl (SIOCDIFADDR)");
  451.         }
  452.     }
  453.     if (newaddr) {
  454.         strncpy(rafp->af_addreq, name, sizeof ifr.ifr_name);
  455.         if (ioctl(s, rafp->af_aifaddr, rafp->af_addreq) < 0)
  456.             Perror("ioctl (SIOCAIFADDR)");
  457.     }
  458.     exit(0);
  459. }
  460. #define RIDADDR 0
  461. #define ADDR    1
  462. #define MASK    2
  463. #define DSTADDR    3
  464.  
  465. /*ARGSUSED*/
  466. void
  467. setifaddr(char *addr, short param)
  468. {
  469.     /*
  470.      * Delay the ioctl to set the interface addr until flags are all set.
  471.      * The address interpretation may depend on the flags,
  472.      * and the flags may change when the address is set.
  473.      */
  474.     setaddr++;
  475.     if (doalias == 0)
  476.         clearaddr = 1;
  477.     (*afp->af_getaddr)(addr, (doalias >= 0 ? ADDR : RIDADDR));
  478. }
  479.  
  480. void
  481. setifnetmask(char *addr, short dummy)
  482. {
  483.     (*afp->af_getaddr)(addr, MASK);
  484. }
  485.  
  486. void
  487. setifbroadaddr(char *addr, short summy)
  488. {
  489.     (*afp->af_getaddr)(addr, DSTADDR);
  490. }
  491.  
  492. void
  493. setifipdst(char *addr, short dummy)
  494. {
  495.     in_getaddr(addr, DSTADDR);
  496.     setipdst++;
  497.     clearaddr = 0;
  498.     newaddr = 0;
  499. }
  500.  
  501. #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
  502.  
  503. void
  504. notealias(char *addr, short param)
  505. {
  506.     if (setaddr && doalias == 0 && param < 0)
  507.         bcopy((caddr_t)rqtosa(af_addreq),
  508.               (caddr_t)rqtosa(af_ridreq),
  509.               rqtosa(af_addreq)->sa_len);
  510.     doalias = param;
  511.     if (param < 0) {
  512.         clearaddr = 1;
  513.         newaddr = 0;
  514.     } else
  515.         clearaddr = 0;
  516. }
  517.  
  518. /*ARGSUSED*/
  519. void
  520. setifdstaddr(char *addr, short param)
  521. {
  522.     (*afp->af_getaddr)(addr, DSTADDR);
  523. }
  524.  
  525. void
  526. setifflags(char *vname, short value)
  527. {
  528.      if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
  529.          Perror("ioctl (SIOCGIFFLAGS)");
  530.          exit(1);
  531.      }
  532.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  533.      flags = ifr.ifr_flags;
  534.  
  535.     if (value < 0) {
  536.         value = -value;
  537.         flags &= ~value;
  538.     } else
  539.         flags |= value;
  540.     ifr.ifr_flags = flags;
  541.     if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
  542.         Perror(vname);
  543. }
  544.  
  545. void
  546. setifmetric(char *val, short dummy)
  547. {
  548.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  549.     ifr.ifr_metric = atoi(val);
  550.     if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0)
  551.         perror("ioctl (set metric)");
  552. }
  553. #ifdef ISO
  554. void
  555. setsnpaoffset(char *val, short dummy)
  556. {
  557.     iso_addreq.ifra_snpaoffset = atoi(val);
  558. }
  559. #endif
  560. #define    IFFBITS \
  561. "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
  562. "
  563.  
  564. /*
  565.  * Print the status of the interface.  If an address family was
  566.  * specified, show it and it only; otherwise, show them all.
  567.  */
  568. void
  569. status(void)
  570. {
  571.     register struct afswtch *p = afp;
  572.     short af = ifr.ifr_addr.sa_family;
  573.  
  574.     printf("%s: ", name);
  575.     printb("flags", flags, IFFBITS);
  576.     if (metric)
  577.         printf(" metric %d", metric);
  578.     putchar('\n');
  579.     if ((p = afp) != NULL) {
  580.         (*p->af_status)(1);
  581.     } else for (p = afs; p->af_name; p++) {
  582.         ifr.ifr_addr.sa_family = p->af_af;
  583.         (*p->af_status)(0);
  584.     }
  585. }
  586.  
  587. void
  588. in_status(int force)
  589. {
  590.     struct sockaddr_in *sin;
  591.  
  592.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  593.     if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
  594.         if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
  595.             if (!force)
  596.                 return;
  597.             bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  598.         } else
  599.             perror("ioctl (SIOCGIFADDR)");
  600.     }
  601.     sin = (struct sockaddr_in *)&ifr.ifr_addr;
  602.     printf("\tinet %s ", inet_ntoa(sin->sin_addr));
  603.     strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  604.     if (ioctl(s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) {
  605.         if (errno != EADDRNOTAVAIL)
  606.             perror("ioctl (SIOCGIFNETMASK)");
  607.         bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  608.     } else
  609.         netmask.sin_addr =
  610.             ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
  611.     if (flags & IFF_POINTOPOINT) {
  612.         if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
  613.             if (errno == EADDRNOTAVAIL)
  614.                 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  615.             else
  616.                 perror("ioctl (SIOCGIFDSTADDR)");
  617.         }
  618.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  619.         sin = (struct sockaddr_in *)&ifr.ifr_dstaddr;
  620.         printf("--> %s ", inet_ntoa(sin->sin_addr));
  621.     }
  622.     printf("netmask %x ", ntohl(netmask.sin_addr.s_addr));
  623.     if (flags & IFF_BROADCAST) {
  624.         if (ioctl(s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) {
  625.             if (errno == EADDRNOTAVAIL)
  626.                 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  627.             else
  628.                 perror("ioctl (SIOCGIFADDR)");
  629.         }
  630.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  631.         sin = (struct sockaddr_in *)&ifr.ifr_addr;
  632.         if (sin->sin_addr.s_addr != 0)
  633.             printf("broadcast %s", inet_ntoa(sin->sin_addr));
  634.     }
  635.     putchar('\n');
  636. }
  637.  
  638. #ifdef NS
  639. xns_status(force)
  640.     int force;
  641. {
  642.     struct sockaddr_ns *sns;
  643.  
  644.     close(s);
  645.     s = socket(AF_NS, SOCK_DGRAM, 0);
  646.     if (s < 0) {
  647.         if (errno == EPROTONOSUPPORT)
  648.             return;
  649.         perror("ifconfig: socket");
  650.         exit(1);
  651.     }
  652.     if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
  653.         if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
  654.             if (!force)
  655.                 return;
  656.             bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  657.         } else
  658.             perror("ioctl (SIOCGIFADDR)");
  659.     }
  660.     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  661.     sns = (struct sockaddr_ns *)&ifr.ifr_addr;
  662.     printf("\tns %s ", ns_ntoa(sns->sns_addr));
  663.     if (flags & IFF_POINTOPOINT) { /* by W. Nesheim@Cornell */
  664.         if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
  665.             if (errno == EADDRNOTAVAIL)
  666.                 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
  667.             else
  668.                 Perror("ioctl (SIOCGIFDSTADDR)");
  669.         }
  670.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  671.         sns = (struct sockaddr_ns *)&ifr.ifr_dstaddr;
  672.         printf("--> %s ", ns_ntoa(sns->sns_addr));
  673.     }
  674.     putchar('\n');
  675. }
  676. #endif
  677. #ifdef ISO
  678. iso_status(force)
  679.     int force;
  680. {
  681.     struct sockaddr_iso *siso;
  682.     struct iso_ifreq ifr;
  683.  
  684.     close(s);
  685.     s = socket(AF_ISO, SOCK_DGRAM, 0);
  686.     if (s < 0) {
  687.         if (errno == EPROTONOSUPPORT)
  688.             return;
  689.         perror("ifconfig: socket");
  690.         exit(1);
  691.     }
  692.     bzero((caddr_t)&ifr, sizeof(ifr));
  693.     strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
  694.     if (ioctl(s, SIOCGIFADDR_ISO, (caddr_t)&ifr) < 0) {
  695.         if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
  696.             if (!force)
  697.                 return;
  698.             bzero((char *)&ifr.ifr_Addr, sizeof(ifr.ifr_Addr));
  699.         } else {
  700.             perror("ioctl (SIOCGIFADDR_ISO)");
  701.             exit(1);
  702.         }
  703.     }
  704.     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
  705.     siso = &ifr.ifr_Addr;
  706.     printf("\tiso %s ", iso_ntoa(&siso->siso_addr));
  707.     if (ioctl(s, SIOCGIFNETMASK_ISO, (caddr_t)&ifr) < 0) {
  708.         if (errno != EADDRNOTAVAIL)
  709.             perror("ioctl (SIOCGIFNETMASK_ISO)");
  710.     } else {
  711.         printf(" netmask %s ", iso_ntoa(&siso->siso_addr));
  712.     }
  713.     if (flags & IFF_POINTOPOINT) {
  714.         if (ioctl(s, SIOCGIFDSTADDR_ISO, (caddr_t)&ifr) < 0) {
  715.             if (errno == EADDRNOTAVAIL)
  716.                 bzero((char *)&ifr.ifr_Addr, sizeof(ifr.ifr_Addr));
  717.             else
  718.                 Perror("ioctl (SIOCGIFDSTADDR_ISO)");
  719.         }
  720.         strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
  721.         siso = &ifr.ifr_Addr;
  722.         printf("--> %s ", iso_ntoa(&siso->siso_addr));
  723.     }
  724.     putchar('\n');
  725. }
  726. #endif
  727.  
  728. void
  729. Perror(char *cmd)
  730. {
  731.     extern int errno;
  732.  
  733.     fprintf(stderr, "ifconfig: ");
  734.     switch (errno) {
  735.  
  736.     case ENXIO:
  737.         fprintf(stderr, "%s: no such interface\n", cmd);
  738.         break;
  739.  
  740.     case EPERM:
  741.         fprintf(stderr, "%s: permission denied\n", cmd);
  742.         break;
  743.  
  744.     default:
  745.         perror(cmd);
  746.     }
  747.     exit(1);
  748. }
  749.  
  750. #define SIN(x) ((struct sockaddr_in *) &(x))
  751. struct sockaddr_in *sintab[] = {
  752. SIN(ridreq.ifr_addr), SIN(addreq.ifra_addr),
  753. SIN(addreq.ifra_mask), SIN(addreq.ifra_broadaddr)};
  754.  
  755. void
  756. in_getaddr(char *s, int which)
  757. {
  758.     register struct sockaddr_in *sin = sintab[which];
  759.     struct hostent *hp;
  760.     struct netent *np;
  761.     int val;
  762.  
  763.     sin->sin_len = sizeof(*sin);
  764.     if (which != MASK)
  765.         sin->sin_family = AF_INET;
  766.  
  767.     if ((val = inet_addr(s)) != -1)
  768.         sin->sin_addr.s_addr = val;
  769.     else if (hp = gethostbyname(s))
  770.         bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
  771.     else if (np = getnetbyname(s))
  772.         sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
  773.     else {
  774.         fprintf(stderr, "%s: bad value\n", s);
  775.         exit(1);
  776.     }
  777. }
  778.  
  779. /*
  780.  * Print a value a la the %b format of the kernel's printf
  781.  */
  782. void
  783. printb(char *s, register unsigned short v, register char *bits)
  784. {
  785.     register int i, any = 0;
  786.     register char c;
  787.  
  788.     if (bits && *bits == 8)
  789.         printf("%s=%o", s, v);
  790.     else
  791.         printf("%s=%x", s, v);
  792.     bits++;
  793.     if (bits) {
  794.         putchar('<');
  795.         while (i = *bits++) {
  796.             if (v & (1 << (i-1))) {
  797.                 if (any)
  798.                     putchar(',');
  799.                 any = 1;
  800.                 for (; (c = *bits) > 32; bits++)
  801.                     putchar(c);
  802.             } else
  803.                 for (; *bits > 32; bits++)
  804.                     ;
  805.         }
  806.         putchar('>');
  807.     }
  808. }
  809.  
  810. #ifdef NS
  811. #define SNS(x) ((struct sockaddr_ns *) &(x))
  812. struct sockaddr_ns *snstab[] = {
  813. SNS(ridreq.ifr_addr), SNS(addreq.ifra_addr),
  814. SNS(addreq.ifra_mask), SNS(addreq.ifra_broadaddr)};
  815.  
  816. xns_getaddr(addr, which)
  817. char *addr;
  818. {
  819.     struct sockaddr_ns *sns = snstab[which];
  820.     struct ns_addr ns_addr();
  821.  
  822.     sns->sns_family = AF_NS;
  823.     sns->sns_len = sizeof(*sns);
  824.     sns->sns_addr = ns_addr(addr);
  825.     if (which == MASK)
  826.         printf("Attempt to set XNS netmask will be ineffectual\n");
  827. }
  828. #endif
  829.  
  830. #ifdef ISO
  831. #define SISO(x) ((struct sockaddr_iso *) &(x))
  832. struct sockaddr_iso *sisotab[] = {
  833. SISO(iso_ridreq.ifr_Addr), SISO(iso_addreq.ifra_addr),
  834. SISO(iso_addreq.ifra_mask), SISO(iso_addreq.ifra_dstaddr)};
  835.  
  836. iso_getaddr(addr, which)
  837. char *addr;
  838. {
  839.     register struct sockaddr_iso *siso = sisotab[which];
  840.     struct iso_addr *iso_addr();
  841.     siso->siso_addr = *iso_addr(addr);
  842.  
  843.     if (which == MASK) {
  844.         siso->siso_len = TSEL(siso) - (caddr_t)(siso);
  845.         siso->siso_nlen = 0;
  846.     } else {
  847.         siso->siso_len = sizeof(*siso);
  848.         siso->siso_family = AF_ISO;
  849.     }
  850. }
  851.  
  852. void
  853. setnsellength(char *val, short dummy)
  854. {
  855.     nsellength = atoi(val);
  856.     if (nsellength < 0) {
  857.         fprintf(stderr, "Negative NSEL length is absurd\n");
  858.         exit (1);
  859.     }
  860.     if (afp == 0 || afp->af_af != AF_ISO) {
  861.         fprintf(stderr, "Setting NSEL length valid only for iso\n");
  862.         exit (1);
  863.     }
  864. }
  865.  
  866. fixnsel(s)
  867. register struct sockaddr_iso *s;
  868. {
  869.     if (s->siso_family == 0)
  870.         return;
  871.     s->siso_tlen = nsellength;
  872. }
  873.  
  874. adjust_nsellength()
  875. {
  876.     fixnsel(sisotab[RIDADDR]);
  877.     fixnsel(sisotab[ADDR]);
  878.     fixnsel(sisotab[DSTADDR]);
  879. }
  880. #endif
  881.